<?php

class Template 
{

	public $tpl_dir;
	private $obj_dir;

	public $tpl_file;
	private $obj_file;

	public $vars;
	public $force = 0;

	private $_var_regexp = "\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*";
	private $_vtag_regexp = "\<\?=(\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*)\?\>";
	private $_const_regexp = "\{([\w]+)\}";

	public $debug = 1;
	public $language = '';

	function __construct($skin_dir='default',$lang_dir='zh') {
		$this->lang_dir = ROOT_DIR.'language'.DIRECTORY_SEPARATOR.$lang_dir;
		$this->tpl_dir = ROOT_DIR.'view'.DIRECTORY_SEPARATOR.$skin_dir;
		$this->obj_dir = DATA_DIR.'view'.DIRECTORY_SEPARATOR.$lang_dir;	
		if (!file_exists($this->obj_dir)) {
			@mkdir($this->obj_dir);
		}
	}
	
	//note  publlic
	function assign($k, $v) {
		$this->vars[$k] = $v;
	}

	//note  publlic
	function display($file) {
		extract($this->vars, EXTR_SKIP);
		include $this->getTpl($file);
	}

	function getTpl($file) {
		$this->tpl_file = $this->tpl_dir.DIRECTORY_SEPARATOR.$file.'.htm';
		$this->obj_file = $this->obj_dir.DIRECTORY_SEPARATOR.$file.'.php';
		if (!file_exists($this->tpl_file)) {
			if ($this->debug) {
				exit("<center><font face=verdana style='font-size: 8pt' color=red><b>Error :</b> File Not Found [$this->tpl_file] </font></center>");
			}
		}
		//compared with expired file
		if ($this->force || @filemtime($this->obj_file) < filemtime($this->tpl_file)) {
			if (empty($this->language)) {
				include $this->lang_dir.DIRECTORY_SEPARATOR.'common.php';
				$this->languages = &$languages;
			}
			$this->complie();
		}
		return $this->obj_file;
	}

	function  complie() {
		$template = file_get_contents($this->tpl_file);
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
		$template = preg_replace("/\{lang\s+(\w+?)\}/ise", "\$this->lang('\\1')", $template);

		$template = preg_replace("/\{($this->_var_regexp)\}/", "<?=\\1?>", $template);
		$template = preg_replace("/(?<!\<\?\=|\\\\)$this->_var_regexp/", "<?=\\0?>", $template);
		
		$template = preg_replace("/\{($this->_const_regexp)\}/", "<?=\\1?>", $template);
		$template = preg_replace("/$this->_const_regexp/", "<?=\\1?>", $template);
		
		$template = preg_replace("/\{\{eval (.*?)\}\}/ies", "\$this->stripvtag('<? \\1?>')", $template);
		$template = preg_replace("/\{eval (.*?)\}/ies", "\$this->stripvtag('<? \\1?>')", $template);
		
		$template = preg_replace("/\{for (.*?)\}/ies", "\$this->stripvtag('<? for(\\1) {?>')", $template);
		$template = preg_replace("/\{\/for\}/is", "<? } ?>", $template);
		
		$template = preg_replace("/\{if\s+(.+?)\}/ies", "\$this->stripvtag('<? if (\\1) { ?>')", $template);
		$template = preg_replace("/\{elseif\s+(.+?)\}/ies", "\$this->stripvtag('<? } elseif(\\1) { ?>')", $template);
		$template = preg_replace("/\{else\}/is", "<? } else { ?>", $template);
		$template = preg_replace("/\{\/if\}/is", "<? } ?>", $template);
		
		for($i=0; $i<2; $i++) {
			$template = preg_replace("/\{loop\s+$this->_vtag_regexp\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopsection('\\1', '\\2', '\\3', '\\4')", $template);
			$template = preg_replace("/\{loop\s+$this->_vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopsection('\\1', '', '\\2', '\\3')", $template);
		}

		$template = preg_replace("/\{include\s+(\w+?)\}/is", "<? include \$this->getTpl('\\1');?>", $template);
		$template = preg_replace("/\{include\s+(.+?)\}/ise", "\$this->stripvtag('<? include \$this->getTpl(\\1); ?>')", $template);


		$template = "<? if(!defined('ROOT_DIR')) exit('Access Denied');?>\r\n$template";
		$template = preg_replace("/(\\\$[a-zA-Z_]\w+\[)([a-zA-Z_]\w+)\]/i", "\\1'\\2']", $template);

 		file_put_contents($this->obj_file, $template);
	}

	function stripvtag($s) {
		return preg_replace("/$this->_vtag_regexp/is", "\\1", str_replace("\\\"", '"', $s));
	}

	function loopscetion($arr, $k, $v, $statement) {
		$arr = $this->stripvtag($arr);
		$k = $this->stripvtag($k);
		$v = $this->stripvtag($v);
		$statement = str_replace("\\\"", '"', $statement);
		return $k ? "<? foreach((array)$arr as $k=>$v) {?>$statement<?}?>" : "<? foreach((array)$arr as $v) {?>$statement<? } ?>";
	}

	function lang($k) {
		return !empty($this->languages[$k]) ? $this->languages[$k] : "{ $k }";
	}
}

/*

PHP Usage:
require_once 'lib/template.class.php';
$this->view = new template();
$this->view->assign('page', $page);
$this->view->assign('userlist', $userlist);
$this->view->display("user_ls");

*/

?>